<template>
  <div class="luckysheet-container">
    <!-- 工具栏 -->
    <div class="toolbar">
      <slot name="toolbar-extra"></slot>
      <el-button @click="handleReset">重置</el-button>
      <el-button type="primary" @click="handleSave" :loading="saving">保存</el-button>
      <el-button @click="handleExport">导出Excel</el-button>
    </div>

    <!-- Luckysheet 容器 -->
    <div class="luckysheet-wrapper" :style="{ height: heightValue + 'px' }">
      <div id="luckysheet" :style="{ height: heightValue + 'px', width: '100%' }"></div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import 'jquery-mousewheel'
// 引入 spectrum 颜色选择器（Luckysheet 需要）
// 注意：spectrum-colorpicker2 会自动注册到 jQuery，需要在 jQuery 之后加载
import 'spectrum-colorpicker2/dist/spectrum.min.css'
import 'spectrum-colorpicker2/dist/spectrum.min.js'
import 'luckysheet/dist/plugins/css/pluginsCss.css'
import 'luckysheet/dist/plugins/plugins.css'
import 'luckysheet/dist/assets/iconfont/iconfont.css'
import 'luckysheet/dist/css/luckysheet.css'
import luckysheet from 'luckysheet'

const props = defineProps({
  url: {
    type: String,
    default: ''
  },
  file: {
    type: [Blob, ArrayBuffer],
    default: null
  },
  editable: {
    type: Boolean,
    default: true
  },
  height: {
    type: [String, Number],
    default: 600
  }
})

const emit = defineEmits(['save', 'change'])

let luckysheetInstance = null
const saving = ref(false)
const originalData = ref(null)
const isInitialized = ref(false)
let wheelHandlerRef = null
let wheelHandlerContainer = null
// 定时器集合，用于统一清理
const timers = new Set()
// Luckysheet 事件监听器引用
let updatedHandlerRef = null
const heightValue = computed(() => {
  return typeof props.height === 'number' ? props.height : parseInt(props.height) || 500
})

// 清理所有定时器和监听器
const cleanup = () => {
  // 清理所有定时器
  timers.forEach((timerId) => {
    clearTimeout(timerId)
  })
  timers.clear()

  // 清理 wheel 事件监听器
  if (wheelHandlerRef && wheelHandlerContainer) {
    try {
      wheelHandlerContainer.removeEventListener('wheel', wheelHandlerRef, { capture: true })
    } catch (e) {
      // 忽略移除错误
    }
    wheelHandlerRef = null
    wheelHandlerContainer = null
  }

  // 清理 Luckysheet 事件监听器
  if (updatedHandlerRef && luckysheet && typeof luckysheet.unbind === 'function') {
    try {
      luckysheet.unbind('updated', updatedHandlerRef)
    } catch (e) {
      // 忽略移除错误
    }
    updatedHandlerRef = null
  } else if (
    updatedHandlerRef &&
    window.luckysheet &&
    typeof window.luckysheet.unbind === 'function'
  ) {
    try {
      window.luckysheet.unbind('updated', updatedHandlerRef)
    } catch (e) {
      // 忽略移除错误
    }
    updatedHandlerRef = null
  }
}

// 创建可追踪的定时器
const createTimer = (callback, delay) => {
  const timerId = setTimeout(() => {
    timers.delete(timerId)
    callback()
  }, delay)
  timers.add(timerId)
  return timerId
}

// 确保 spectrum 颜色选择器在全局可用
const ensureSpectrumLoaded = () => {
  return new Promise((resolve) => {
    // 检查 spectrum 是否已经加载
    if (window.$ && typeof window.$.fn.spectrum === 'function') {
      resolve()
      return
    }

    // 如果 spectrum 未加载，尝试动态导入
    if (typeof window.$ !== 'undefined') {
      // 等待一小段时间，让 spectrum 有时间注册
      setTimeout(() => {
        if (window.$ && typeof window.$.fn.spectrum === 'function') {
          resolve()
        } else {
          // 如果仍然未加载，尝试手动注册
          try {
            // spectrum-colorpicker2 通常会自动注册到 jQuery
            // 如果未自动注册，可能需要手动处理
            console.warn('Spectrum 颜色选择器可能未正确加载，颜色功能可能不可用')
          } catch (e) {
            console.warn('Spectrum 初始化警告:', e)
          }
          resolve() // 即使失败也继续，避免阻塞
        }
      }, 100)
    } else {
      resolve() // jQuery 未加载时也继续
    }
  })
}

const loadLuckysheet = () => {
  return new Promise((resolve, reject) => {
    try {
      if (luckysheet && typeof luckysheet.create === 'function') {
        if (!window.luckysheet) {
          window.luckysheet = luckysheet
        }
        resolve()
      } else {
        reject(new Error('Luckysheet 导入失败，请检查依赖是否正确安装'))
      }
    } catch (error) {
      reject(new Error('Luckysheet 导入失败: ' + error.message))
    }
  })
}

// 从 URL 或文件流加载 Excel 数据
const loadExcelData = async () => {
  try {
    let arrayBuffer = null

    if (props.file) {
      // 从文件流加载
      if (props.file instanceof Blob) {
        arrayBuffer = await props.file.arrayBuffer()
      } else if (props.file instanceof ArrayBuffer) {
        arrayBuffer = props.file
      }
    } else if (props.url) {
      // 从 URL 加载
      const response = await fetch(props.url)
      if (!response.ok) {
        throw new Error('加载 Excel 文件失败')
      }
      arrayBuffer = await response.arrayBuffer()
    }

    return arrayBuffer
  } catch (error) {
    ElMessage.error('加载 Excel 文件失败: ' + (error.message || '未知错误'))
    return null
  }
}

const initLuckysheet = async (data = null) => {
  try {
    // 先清理所有旧的定时器和监听器
    cleanup()

    // 确保 spectrum 颜色选择器已加载
    await ensureSpectrumLoaded()

    await loadLuckysheet()

    if (luckysheetInstance && luckysheet && luckysheet.destroy) {
      luckysheet.destroy()
      luckysheetInstance = null
    }
    const defaultData = [
      {
        name: 'Sheet1',
        index: '0',
        order: 0,
        status: 1,
        celldata: [],
        config: {},
        scrollLeft: 0,
        scrollTop: 0,
        luckysheet_select_save: [],
        calcchain: [],
        isPivotTable: false,
        pivotTable: {},
        zoomRatio: 1,
        image: [],
        showGridLines: 1,
        defaultRowHeight: 19,
        defaultColWidth: 73
      }
    ]

    const options = {
      container: 'luckysheet',
      lang: 'zh',
      allowEdit: props.editable,
      allowCopy: true,
      allowDelete: true,
      allowInsert: true,
      showtoolbar: props.editable, // 显示工具栏
      showinfobar: false, // 隐藏信息栏
      showsheetbar: true, // 显示工作表栏
      showstatisticBar: true, // 显示统计栏
      enableAddRow: props.editable,
      enableAddBackTop: props.editable,
      enablePage: props.editable,
      data: data || defaultData,
      plugins: []
    }

    if (data === null) {
      const arrayBuffer = await loadExcelData()
      if (arrayBuffer) {
        const excelData = await convertExcelToLuckysheet(arrayBuffer)
        if (excelData) {
          options.data = excelData
        }
      }
    }

    if (typeof window.$ === 'undefined') {
      throw new Error('jQuery 未加载，请检查入口文件的 jQuery 导入')
    }

    // 检查并确保 mousewheel 插件已加载，如果没有则提供 polyfill
    if (typeof window.$.fn.mousewheel === 'undefined') {
      // 等待一小段时间，让插件有时间注册
      await new Promise((resolve) => setTimeout(resolve, 100))
      if (typeof window.$.fn.mousewheel === 'undefined') {
        // 提供 polyfill，将 wheel 事件转换为 mousewheel 事件
        window.$.fn.mousewheel = function (handler) {
          return this.on('wheel', function (e) {
            const delta = e.originalEvent.deltaY
            // 将 wheel 事件的 deltaY 转换为 mousewheel 事件的 delta
            // wheel 事件：deltaY > 0 向下滚动，deltaY < 0 向上滚动
            // mousewheel 事件：delta > 0 向上滚动，delta < 0 向下滚动（传统约定）
            // 所以需要反转符号
            const normalizedDelta = -delta
            handler.call(this, e, normalizedDelta, e.originalEvent)
          })
        }
        console.log('已提供 jquery-mousewheel polyfill')
      }
    }

    if (!luckysheet) {
      throw new Error('Luckysheet 未正确导入，请检查依赖是否正确安装')
    }

    if (typeof luckysheet.create !== 'function') {
      throw new Error('Luckysheet API 不正确，请检查版本兼容性')
    }

    try {
      if (luckysheetInstance && luckysheet && luckysheet.destroy) {
        try {
          luckysheet.destroy()
        } catch (e) {
          // 忽略销毁错误
        }
        luckysheetInstance = null
        isInitialized.value = false
      }

      await nextTick()

      let container = document.getElementById('luckysheet')
      if (!container) {
        await new Promise((resolve) => setTimeout(resolve, 200))
        const retryContainer = document.getElementById('luckysheet')
        if (!retryContainer) {
          throw new Error('找不到容器元素 #luckysheet')
        }
        container = retryContainer
      }

      container.innerHTML = ''
      container.style.height = heightValue.value + 'px'
      container.style.width = '100%'
      container.style.position = 'relative'

      luckysheet.create(options)
      luckysheetInstance = luckysheet
      window.luckysheet = luckysheet

      // 等待 Luckysheet 初始化完成后，修复滚轮滚动方向
      // 导入数据后需要更长时间等待 DOM 渲染完成
      createTimer(
        () => {
          fixScrollDirectionAfterInit(container)
        },
        data ? 2500 : 1500
      )

      let retryCount = 0
      const maxRetries = 20
      let gridContainer = null
      while (retryCount < maxRetries) {
        await new Promise((resolve) => setTimeout(resolve, 150))
        gridContainer =
          container.querySelector('.luckysheet-grid-window') ||
          container.querySelector('.luckysheet-wa-editor') ||
          container.querySelector('[class*="grid"]')
        if (gridContainer) {
          break
        }
        retryCount++
      }

      if (gridContainer) {
        // 可以在这里添加其他初始化逻辑
      }
    } catch (error) {
      throw new Error('Luckysheet 初始化失败: ' + (error.message || '未知错误'))
    }

    if (options.data) {
      originalData.value = JSON.parse(JSON.stringify(options.data))
    }

    if (props.editable && luckysheet) {
      // 创建事件处理器并保存引用
      updatedHandlerRef = () => {
        emit('change', {
          data: luckysheet.getAllSheets()
        })
      }

      if (typeof luckysheet.bind === 'function') {
        try {
          luckysheet.bind('updated', updatedHandlerRef)
        } catch (e) {
          // 忽略事件绑定错误
          updatedHandlerRef = null
        }
      } else if (window.luckysheet && typeof window.luckysheet.bind === 'function') {
        try {
          window.luckysheet.bind('updated', updatedHandlerRef)
        } catch (e) {
          // 忽略事件绑定错误
          updatedHandlerRef = null
        }
      }
    }

    isInitialized.value = true
  } catch (error) {
    ElMessage.error('初始化表格失败: ' + (error.message || '未知错误'))
  }
}

const convertExcelToLuckysheet = async (arrayBuffer) => {
  try {
    const XLSX = await import('xlsx')
    const workbook = XLSX.read(arrayBuffer, {
      type: 'array',
      cellDates: true,
      cellNF: false,
      cellText: false
    })

    const firstSheetName = workbook.SheetNames[0]
    const worksheet = workbook.Sheets[firstSheetName]
    const merges = worksheet['!merges'] || []

    if (window.luckysheet && typeof window.luckysheet.transformExcelToLucky === 'function') {
      const luckysheetData = window.luckysheet.transformExcelToLucky(worksheet)
      if (luckysheetData.config && !luckysheetData.config.merge) {
        luckysheetData.config.merge = {}
      }
      merges.forEach((merge) => {
        const key = `${merge.s.r}_${merge.s.c}`
        if (!luckysheetData.config.merge) {
          luckysheetData.config.merge = {}
        }
        luckysheetData.config.merge[key] = {
          r: merge.s.r,
          c: merge.s.c,
          rs: merge.e.r - merge.s.r + 1,
          cs: merge.e.c - merge.s.c + 1
        }
      })

      return [
        {
          name: firstSheetName,
          index: '0',
          order: 0,
          status: 1,
          ...luckysheetData
        }
      ]
    } else {
      const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: '' })

      const celldata = []
      jsonData.forEach((row, rowIndex) => {
        row.forEach((cell, colIndex) => {
          if (cell !== '') {
            celldata.push({
              r: rowIndex,
              c: colIndex,
              v: {
                v: cell,
                ct: { fa: 'General', t: 'g' },
                m: String(cell)
              }
            })
          }
        })
      })

      const mergeConfig = {}
      merges.forEach((merge) => {
        const key = `${merge.s.r}_${merge.s.c}`
        mergeConfig[key] = {
          r: merge.s.r,
          c: merge.s.c,
          rs: merge.e.r - merge.s.r + 1,
          cs: merge.e.c - merge.s.c + 1
        }
      })

      return [
        {
          name: firstSheetName,
          index: '0',
          order: 0,
          status: 1,
          celldata: celldata,
          config: {
            merge: mergeConfig
          },
          scrollLeft: 0,
          scrollTop: 0,
          luckysheet_select_save: [],
          calcchain: [],
          isPivotTable: false,
          pivotTable: {},
          zoomRatio: 1,
          image: [],
          showGridLines: 1,
          defaultRowHeight: 19,
          defaultColWidth: 73
        }
      ]
    }
  } catch (error) {
    return null
  }
}

const exportToExcel = async () => {
  try {
    if (!luckysheetInstance) {
      return null
    }

    const sheets = luckysheet ? luckysheet.getAllSheets() : []
    if (!sheets || sheets.length === 0) {
      ElMessage.warning('没有数据可导出')
      return null
    }

    if (luckysheet && luckysheet.exportExcel) {
      const excelBlob = luckysheet.exportExcel(sheets, '技术参数')
      return excelBlob
    } else {
      const XLSX = await import('xlsx')
      const wb = XLSX.utils.book_new()

      sheets.forEach((sheet) => {
        const wsData = []
        if (sheet.celldata && sheet.celldata.length > 0) {
          sheet.celldata.forEach((cell) => {
            const row = cell.r
            const col = cell.c
            const value = cell.v ? cell.v.m || cell.v.v || '' : ''

            if (!wsData[row]) {
              wsData[row] = []
            }
            wsData[row][col] = value
          })
        }

        const ws = XLSX.utils.aoa_to_sheet(wsData)

        if (sheet.config && sheet.config.merge) {
          const merges = []
          Object.keys(sheet.config.merge).forEach((key) => {
            const merge = sheet.config.merge[key]
            merges.push({
              s: { r: merge.r, c: merge.c },
              e: { r: merge.r + merge.rs - 1, c: merge.c + merge.cs - 1 }
            })
          })
          if (merges.length > 0) {
            ws['!merges'] = merges
          }
        }

        XLSX.utils.book_append_sheet(wb, ws, sheet.name || 'Sheet1')
      })

      const wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'array' })
      return new Blob([wbout], {
        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      })
    }
  } catch (error) {
    ElMessage.error('导出失败: ' + (error.message || '未知错误'))
    return null
  }
}

const handleSave = async () => {
  if (!props.editable || !luckysheetInstance) {
    return
  }

  saving.value = true
  try {
    const excelBlob = await exportToExcel()
    if (!excelBlob) {
      saving.value = false
      return
    }

    const sheets = luckysheet ? luckysheet.getAllSheets() : []

    emit('save', {
      file: excelBlob,
      data: sheets,
      fileName: `excel_${new Date().getTime()}.xlsx`
    })

    if (sheets && sheets.length > 0) {
      originalData.value = JSON.parse(JSON.stringify(sheets))
    }
  } catch (error) {
    // 忽略错误，由外层处理
  } finally {
    saving.value = false
  }
}

const handleReset = () => {
  if (originalData.value && luckysheetInstance && luckysheet && luckysheet.destroy) {
    luckysheet.destroy()
    luckysheetInstance = null
    isInitialized.value = false
    nextTick(() => {
      initLuckysheet(originalData.value)
    })
  }
}

const handleExport = async () => {
  const excelBlob = await exportToExcel()
  if (excelBlob) {
    const url = window.URL.createObjectURL(excelBlob)
    const link = document.createElement('a')
    link.href = url
    link.download = `excel_${new Date().getTime()}.xlsx`
    link.click()
    window.URL.revokeObjectURL(url)
  }
}

watch(
  () => [props.url, props.file],
  async () => {
    if ((props.url || props.file) && isInitialized.value) {
      if (luckysheetInstance && luckysheet && luckysheet.destroy) {
        luckysheet.destroy()
        luckysheetInstance = null
        isInitialized.value = false
      }
      await nextTick()
      await new Promise((resolve) => setTimeout(resolve, 200))
      await initLuckysheet()
    }
  }
)

// 在 Luckysheet 初始化后修复滚轮滚动方向
const fixScrollDirectionAfterInit = (container, retryCount = 0) => {
  try {
    if (!container) {
      // 如果容器不存在，重试
      if (retryCount < 5) {
        createTimer(() => {
          const retryContainer = document.getElementById('luckysheet')
          if (retryContainer) {
            fixScrollDirectionAfterInit(retryContainer, retryCount + 1)
          }
        }, 500)
      }
      return
    }

    // 查找滚动容器：优先查找 Luckysheet 特定容器，否则查找有滚动条样式的容器，最后查找滚动范围最大的容器
    let mainScrollContainer = null

    // 方法1: 查找 Luckysheet 特定容器
    const selectors = [
      '.luckysheet-grid-window',
      '.luckysheet-sheet-container',
      '.luckysheet-grid-main',
      '[class*="grid-window"]'
    ]
    for (const selector of selectors) {
      const el = container.querySelector(selector)
      if (el && el.scrollHeight > el.clientHeight && el.scrollHeight - el.clientHeight > 10) {
        mainScrollContainer = el
        break
      }
    }

    // 方法2: 查找有滚动条样式的容器
    if (!mainScrollContainer) {
      const allElements = container.querySelectorAll('*')
      for (const el of allElements) {
        const style = window.getComputedStyle(el)
        if (
          (style.overflowY === 'auto' || style.overflowY === 'scroll') &&
          el.scrollHeight > el.clientHeight &&
          el.scrollHeight - el.clientHeight > 50
        ) {
          mainScrollContainer = el
          break
        }
      }
    }

    // 方法3: 查找滚动范围最大的容器
    if (!mainScrollContainer) {
      const allElements = container.querySelectorAll('*')
      let maxScroll = 0
      for (const el of allElements) {
        const scroll = el.scrollHeight - el.clientHeight
        if (scroll > maxScroll && scroll > 50) {
          maxScroll = scroll
          mainScrollContainer = el
        }
      }
    }

    // 如果找不到滚动容器，重试
    if (!mainScrollContainer) {
      if (retryCount < 5) {
        createTimer(() => {
          fixScrollDirectionAfterInit(container, retryCount + 1)
        }, 500)
      }
      return
    }

    // 拦截 wheel 事件并手动处理滚动
    const wheelHandler = (e) => {
      if (!container.contains(e.target)) return

      e.preventDefault()
      e.stopPropagation()
      e.stopImmediatePropagation()

      const deltaY = e.deltaY
      const currentScrollTop = mainScrollContainer.scrollTop || 0
      const maxScrollTop = mainScrollContainer.scrollHeight - mainScrollContainer.clientHeight
      const scrollSpeed = deltaY * 0.5
      const newScrollTop = Math.max(0, Math.min(currentScrollTop + scrollSpeed, maxScrollTop))

      mainScrollContainer.scrollTop = newScrollTop
      mainScrollContainer.dispatchEvent(new Event('scroll', { bubbles: true }))
    }

    // 保存事件处理器引用
    wheelHandlerRef = wheelHandler
    wheelHandlerContainer = container

    container.addEventListener('wheel', wheelHandler, { passive: false, capture: true })
  } catch (error) {
    console.warn('修复滚轮滚动方向失败:', error)
    // 出错时也重试
    if (retryCount < 5) {
      createTimer(() => {
        fixScrollDirectionAfterInit(container, retryCount + 1)
      }, 500)
    }
  }
}

const isElementVisible = (element) => {
  if (!element) return false

  const rect = element.getBoundingClientRect()
  const style = window.getComputedStyle(element)
  if (
    rect.width === 0 ||
    rect.height === 0 ||
    style.display === 'none' ||
    style.visibility === 'hidden' ||
    style.opacity === '0'
  ) {
    return false
  }

  let parent = element.parentElement
  while (parent && parent !== document.body) {
    const parentStyle = window.getComputedStyle(parent)
    const parentRect = parent.getBoundingClientRect()

    if (
      parentStyle.display === 'none' ||
      parentStyle.visibility === 'hidden' ||
      parentStyle.opacity === '0' ||
      parentRect.width === 0 ||
      parentRect.height === 0
    ) {
      return false
    }

    if (parent.classList.contains('el-tab-pane')) {
      const isActive = !parent.classList.contains('is-hidden') && parentStyle.display !== 'none'
      if (!isActive) {
        return false
      }
    }

    parent = parent.parentElement
  }

  return true
}

onMounted(async () => {
  await nextTick()
  await new Promise((resolve) => setTimeout(resolve, 200))
  await nextTick()

  let container = document.getElementById('luckysheet')
  let retryCount = 0
  const maxRetries = 30

  while (retryCount < maxRetries) {
    container = document.getElementById('luckysheet')

    if (container && isElementVisible(container)) {
      container.style.display = 'block'
      container.style.visibility = 'visible'
      await new Promise((resolve) => setTimeout(resolve, 200))
      await initLuckysheet()
      return
    }

    await new Promise((resolve) => setTimeout(resolve, 100))
    retryCount++
  }

  container = document.getElementById('luckysheet')
  if (container) {
    container.style.display = 'block'
    container.style.visibility = 'visible'
    await new Promise((resolve) => setTimeout(resolve, 300))
    await initLuckysheet()
  } else {
    ElMessage.error('初始化表格失败：无法找到容器元素')
  }
})

onBeforeUnmount(() => {
  // 清理所有定时器和监听器
  cleanup()

  // 销毁 Luckysheet 实例
  if (luckysheetInstance && luckysheet && luckysheet.destroy) {
    try {
      luckysheet.destroy()
    } catch (error) {
      // 忽略销毁错误
    }
    luckysheetInstance = null
  }
})
defineExpose({
  getData: () => (luckysheetInstance && luckysheet ? luckysheet.getAllSheets() : []),
  save: handleSave,
  reset: handleReset,
  export: handleExport,
  exportToExcel: exportToExcel
})
</script>

<style lang="scss" scoped>
.luckysheet-container {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;

  .toolbar {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 20px;
    padding: 10px;
    background-color: #f5f7fa;
    border-radius: 4px;
  }

  .luckysheet-wrapper {
    width: 100%;
    overflow: visible;
    position: relative;
    background-color: #fff;
  }
}
</style>

<style>
#luckysheet .luckysheet-toolbar .luckysheet-toolbar-btn-group:nth-child(n + 3) {
  display: none !important;
}

#luckysheet .luckysheet-toolbar [data-type='paintFormat'],
#luckysheet .luckysheet-toolbar [data-type='currencyFormat'],
#luckysheet .luckysheet-toolbar [data-type='percentageFormat'],
#luckysheet .luckysheet-toolbar [data-type='numberDecrease'],
#luckysheet .luckysheet-toolbar [data-type='numberIncrease'],
#luckysheet .luckysheet-toolbar [data-type='moreFormats'],
#luckysheet .luckysheet-toolbar [data-type='font'],
#luckysheet .luckysheet-toolbar [data-type='fontSize'],
#luckysheet .luckysheet-toolbar [data-type='bold'],
#luckysheet .luckysheet-toolbar [data-type='italic'],
#luckysheet .luckysheet-toolbar [data-type='strikethrough'],
#luckysheet .luckysheet-toolbar [data-type='underline'],
#luckysheet .luckysheet-toolbar [data-type='textColor'],
#luckysheet .luckysheet-toolbar [data-type='fillColor'],
#luckysheet .luckysheet-toolbar [data-type='border'],
/* 确保文字颜色、单元格颜色、边框工具被隐藏 */
#luckysheet .luckysheet-toolbar .luckysheet-toolbar-btn[data-type='textColor'],
#luckysheet .luckysheet-toolbar .luckysheet-toolbar-btn[data-type='fillColor'],
#luckysheet .luckysheet-toolbar .luckysheet-toolbar-btn[data-type='border'],
#luckysheet .luckysheet-toolbar button[data-type='textColor'],
#luckysheet .luckysheet-toolbar button[data-type='fillColor'],
#luckysheet .luckysheet-toolbar button[data-type='border'],
#luckysheet .luckysheet-toolbar [data-type='horizontalAlignMode'],
#luckysheet .luckysheet-toolbar [data-type='verticalAlignMode'],
#luckysheet .luckysheet-toolbar [data-type='textWrapMode'],
#luckysheet .luckysheet-toolbar [data-type='textMode'],
#luckysheet .luckysheet-toolbar [data-type='image'],
#luckysheet .luckysheet-toolbar [data-type='link'],
#luckysheet .luckysheet-toolbar [data-type='chart'],
#luckysheet .luckysheet-toolbar [data-type='pivotTable'],
#luckysheet .luckysheet-toolbar [data-type='function'],
#luckysheet .luckysheet-toolbar [data-type='frozenMode'],
#luckysheet .luckysheet-toolbar [data-type='sortAndFilter'],
#luckysheet .luckysheet-toolbar [data-type='conditionalFormat'],
#luckysheet .luckysheet-toolbar [data-type='dataVerification'],
#luckysheet .luckysheet-toolbar [data-type='splitColumn'],
#luckysheet .luckysheet-toolbar [data-type='screenshot'],
#luckysheet .luckysheet-toolbar [data-type='findAndReplace'],
#luckysheet .luckysheet-toolbar [data-type='protection'],
#luckysheet .luckysheet-toolbar [data-type='print'] {
  display: none !important;
}
</style>
